
package com.shockweb.client;

import com.shockweb.bridge.DataAgreement;
import com.shockweb.bridge.OperationDefine;
import com.shockweb.common.log.LogManager;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * 客户端接收服务端返回信息的Handler
 * 
 * @author 彭明华
 * 2018年1月4日 创建
 */
public class ClientNettyHandler extends ChannelInboundHandlerAdapter {


	/**
	 * 客户端
	 */
    private Client client = null;

    /**
     * 构造方法
     * @param client 客户端
     */
    public ClientNettyHandler(Client client) {
        this.client = client;
    }
    
    /**
     * 读取服务端返回信息的方法
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buf = null;
        byte[] data = null;
        if (msg instanceof ByteBuf) {
            buf = (ByteBuf) msg;
            if(buf.readableBytes()==0){
            	LogManager.errorLog(this.getClass(), new ClientException("非法的数据长度"));
                buf.release();
                return;
            }
        } else {
            LogManager.errorLog(this.getClass(), new ClientException("非法的数据"));
            return;
        }
        String uuid = null;
        try {
        	data = new byte[buf.readableBytes()];
            buf.readBytes(data);
            uuid = DataAgreement.resolutionUUID(data);
           	client.getContext().setData(uuid, data);
            client.getContext().lockResume(uuid);
        } catch (Exception e) {
            LogManager.errorLog(this.getClass(), e);
            if(uuid!=null){
            	client.getContext().setException(uuid, e);
            	try {
					client.getContext().lockResume(uuid);
				} catch (InterruptedException e1) {
					LogManager.errorLog(this.getClass(), e1);
				}
            }
        } finally {
            buf.release();//手动释放缓冲区
        }
    }
    
    /**
     * 读取完成
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    /**
     * 服务端断开连接触发
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.close();
    }

    /**
     * 产生异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.disconnect();// 服务端发送异常时关闭客户端
        LogManager.errorLog(this.getClass(), "exceptionCaught",cause);
    }

    /**
     * 保持长连接,向服务器发送心跳信息
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        // 超时处理
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.WRITER_IDLE) {
                ByteBufAllocator alloc = ctx.channel().alloc();
                ByteBuf buf = alloc.buffer(DataAgreement.BYTE_LENGTH);
                buf.writeByte(OperationDefine.ALIVE.value());
                ctx.channel().writeAndFlush(buf);
            }else  if (event.state().equals(IdleState.READER_IDLE)) {

            } else if (event.state().equals(IdleState.ALL_IDLE)) {

            }
        }
    }
    
}
